home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Frameworks
/
Grant's CGI Framework 1.0b14
/
Util
/
LogUtil.c
< prev
next >
Wrap
Text File
|
1996-04-11
|
10KB
|
453 lines
/*****
*
* LogUtil.c
*
* Logging functions
*
* This is a support file for "Grant's CGI Framework".
* Please see the license agreement that accompanies the distribution package
* for licensing details.
*
* Copyright ©1995,1996 by Grant Neufeld
* grant@acm.com
* http://arpp.carleton.ca/grant/mac/grantscgi/
*
*****/
#include "MyConfiguration.h"
#if kCompileWithLogSupport
#if !kCompileWithProcessFileSpec
#error "Logging requires the kCompileWithProcessFileSpec to be set on in MyConfiguration.h"
#endif
#include <string.h>
#include "compiler_stuff.h"
#include "constants.h"
#include "globals.h"
#include "DebugUtil.h"
#include "FileUtil.h"
#include "LogUtil.h"
/*** LOCAL VARIABLES ***/
static OSErr vLogInitialized = false; /* logging has been initialized */
static OSErr vLogFileError = true; /* returned if LogStartup fails - logging can't be done */
static FSSpec vLogFileSpec; /* the location of the log file */
static short vLogFileRef = nil; /* the reference of the open log file - nil if closed */
static Boolean vLogNeedsFlush = false; /* there is data that has been written but not flushed */
/*** LOCAL CONSTANTS ***/
#define krLogFileCreatorType 3002
/* default to SimpleText/TeachText if creator type resource not available */
#define kLogFileDefaultCreatorType 'ttxt'
/*** LOCAL MACROS ***/
#define logFileEnsureOpen() ((vLogFileRef == nil)? LogFileOpen() : noErr)
/*** LOCAL PROTOTYPES ***/
/*** FUNCTIONS ***/
/* Initialize the log file. */
OSErr
LogStartup ( void )
{
Str255 logFileName;
Handle logFileCreatorHdl; /* the resource containing the creator type */
OSType creatorType; /* used when creating new log file */
Boolean isFolder; /* used for Finder alias resolving */
Boolean wasAliased; /* used for Finder alias resolving */
vLogInitialized = true;
vLogFileError = noErr;
vLogFileRef = nil;
logFileName[nil] = nil;
vLogNeedsFlush = false;
/* get the name of the log file */
GetIndString ( logFileName, krFilenamesStrs, kriFilenameLog );
if ( logFileName[nil] == nil )
{
/* string of file name is invalid */
vLogFileError = ResError ();
}
/* build the FSSpec */
if ( vLogFileError == noErr )
{
vLogFileError = FSMakeFSSpec ( gProcessFSSpec.vRefNum, gProcessFSSpec.parID,
logFileName, &vLogFileSpec );
}
if ( vLogFileError == fnfErr )
{
/* determine the creator type of the log file */
logFileCreatorHdl = GetResource ( 'TNAM', krLogFileCreatorType );
if ( logFileCreatorHdl != NULL )
{
creatorType = **((OSType **)logFileCreatorHdl);
ReleaseResource ( logFileCreatorHdl );
}
else
{
/* use default if creator type resource not found */
creatorType = kLogFileDefaultCreatorType;
}
vLogFileError = FSpCreate ( &vLogFileSpec, creatorType, kTypeText, smSystemScript );
}
else if ( vLogFileError == noErr )
{
/* resolve if the file is an alias */
vLogFileError = ResolveAliasFileMountOption ( &vLogFileSpec, true, &isFolder, &wasAliased, false );
}
if ( vLogFileError == noErr )
{
vLogFileError = LogFileOpen ();
}
#if kCompileWithDebugLogging
if ( vLogFileError == noErr )
{
LogStringAndSeparatorP ( gProcessFSSpec.name, ' ' );
LogStringBreakP ( gVersionStr );
}
#endif
return vLogFileError;
} /* LogStartup */
/* */
OSErr
LogQuit ( void )
{
OSErr theErr;
if ( (vLogFileError == noErr) && (vLogFileRef != nil) )
{
theErr = LogFileClose ();
}
else
{
theErr = noErr;
}
return theErr;
} /* LogQuit */
#pragma mark -
/* Open the log file for writing. Writing will begin at the end of the file (appending) */
OSErr
LogFileOpen ( void )
{
OSErr theErr;
if ( vLogFileError == noErr )
{
my_assert ( vLogFileRef == nil, "\pLogFileOpen: vLogFileRef is not nil - file already open" );
/* open the data fork for writing */
theErr = FSpOpenDF ( &vLogFileSpec, fsWrPerm, &vLogFileRef );
if ( theErr == noErr )
{
/* set the file position to the end of the file */
theErr = SetFPos ( vLogFileRef, fsFromLEOF, nil );
}
else
{
/* there was an error */
vLogFileRef = nil;
}
}
else
{
theErr = vLogFileError;
}
return theErr;
} /* LogFileOpen */
/* Close the log file. */
OSErr
LogFileClose ( void )
{
OSErr theErr;
if ( vLogFileError == noErr )
{
my_assert ( vLogFileRef != nil, "\pLogFileClose: vLogFileRef is nil" );
theErr = FSClose ( vLogFileRef );
vLogFileRef = nil;
}
else
{
theErr = vLogFileError;
}
return theErr;
} /* LogFileClose */
/* ••• need to upgrade this to just flush the data to disk - but I'm in a rush to
get this at least working...
This function should be called periodically after data has been written to the
log file. It helps to ensure that the data is not lost if there is a crash before
the file is closed. */
p_export
OSErr
LogFileFlush ( void )
{
OSErr theErr;
if ( vLogNeedsFlush )
{
theErr = LogFileClose ();
theErr = LogFileOpen ();
vLogNeedsFlush = false;
}
else
{
theErr = noErr;
}
return theErr;
} /* LogFileFlush */
#pragma mark -
/* Takes a C format string and writes it to the log file.
Does not append linebreak or any other character so the next write to the log file
will follow directly after this write. If you want to have theString followed by
a linebreak, you need to call one of the functions that appends a separator
character after theString. */
p_export
OSErr
LogString ( const char *theString )
{
OSErr theErr;
long stringLength;
my_assert ( theString != NULL, "\pLogString: theString is NULL" );
if ( !vLogInitialized )
{
return noErr;
}
if ( (vLogFileError == noErr) && (theString[nil] != nil) )
{
theErr = logFileEnsureOpen ();
if ( theErr == noErr )
{
stringLength = strlen ( theString );
/* write the line + end null byte to the file */
theErr = FSWrite ( vLogFileRef, &stringLength, theString );
if ( theErr == noErr )
{
vLogNeedsFlush = true;
}
}
}
else
{
theErr = vLogFileError;
}
return theErr;
} /* LogString */
/* Same as 'LogString', except theString is a Pascal format string (max 255 characters) */
p_export
OSErr
LogStringP ( const StringPtr theString )
{
OSErr theErr;
long stringLength;
my_assert ( theString != NULL, "\pLogStringP: theString is NULL" );
if ( !vLogInitialized )
{
return noErr;
}
if ( (vLogFileError == noErr) && (theString[nil] != nil) )
{
theErr = logFileEnsureOpen ();
if ( theErr == noErr )
{
stringLength = (unsigned char) (theString[nil]);
/* write the line + end null byte to the file */
theErr = FSWrite ( vLogFileRef, &stringLength, theString + 1 );
if ( theErr == noErr )
{
vLogNeedsFlush = true;
}
}
}
else
{
theErr = noErr;
}
return theErr;
} /* LogStringP */
/* Takes a C format string and writes it to the log file.
Appends theSeparator after theString. This may be used for writing theString
followed by a linefeed, or perhaps a tab character, among other uses. */
p_export
OSErr
LogStringAndSeparator ( const char *theString, char theSeparator )
{
OSErr theErr;
long stringLength;
my_assert ( theString != NULL, "\pLogStringAndSeparator: theString is NULL" );
if ( !vLogInitialized )
{
return noErr;
}
if ( vLogFileError == noErr )
{
theErr = logFileEnsureOpen ();
if ( theErr == noErr )
{
if ( theString[nil] != nil )
{
stringLength = strlen ( theString );
/* write the line + end null byte to the file */
theErr = FSWrite ( vLogFileRef, &stringLength, theString );
}
/* write the newline char to the file */
stringLength = 1;
theErr = FSWrite ( vLogFileRef, &stringLength, &theSeparator );
if ( theErr == noErr )
{
vLogNeedsFlush = true;
}
}
}
else
{
theErr = noErr;
}
return theErr;
} /* LogStringAndSeparator */
/* Same as 'LogStringAndSeparator', except theString is a Pascal format string
(max 255 characters) */
p_export
OSErr
LogStringAndSeparatorP ( const StringPtr theString, char theSeparator )
{
OSErr theErr;
long stringLength;
my_assert ( theString != NULL, "\pLogStringAndSeparatorP: theString is NULL" );
if ( !vLogInitialized )
{
return noErr;
}
if ( vLogFileError == noErr )
{
theErr = logFileEnsureOpen ();
if ( theErr == noErr )
{
if ( theString[nil] != nil )
{
stringLength = (unsigned char) (theString[nil]);
/* write the line + end null byte to the file */
theErr = FSWrite ( vLogFileRef, &stringLength, theString + 1 );
}
/* write the newline char to the file */
stringLength = 1;
theErr = FSWrite ( vLogFileRef, &stringLength, &theSeparator );
if ( theErr == noErr )
{
vLogNeedsFlush = true;
}
}
}
else
{
theErr = noErr;
}
return theErr;
} /* LogStringAndSeparatorP */
/** DEBUG LOGGING **/
#pragma mark -
#if kCompileWithDebugLogging
/* These functions will prepend "DEBUG: " in the log file before writing theString
that is passed to them.
The functions are prototyped in "LogUtil.h" to map to NULL (do nothing) if
the 'kCompileWithDebugLogging' option is off in "MyConfiguration.h" */
/* */
p_export
OSErr
LogStringDebug ( const char *theString )
{
OSErr theErr;
theErr = LogStringP ( "\pDEBUG: " );
theErr = LogStringAndSeparator ( theString, kLogLinebreak );
return theErr;
} /* LogStringDebug */
/* */
p_export
OSErr
LogStringDebugP ( const StringPtr theString )
{
OSErr theErr;
theErr = LogStringP ( "\pDEBUG: " );
theErr = LogStringAndSeparatorP ( theString, kLogLinebreak );
return theErr;
} /* LogStringDebugP */
#endif /* kCompileWithDebugLogging */
#endif /* kCompileWithLogSupport */
/***** EOF *****/